package cn.asiontang.xposed.url_firewall;


import android.app.Activity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;

import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import cn.asiontang.xposed.LogEx;

public class MainActivity extends Activity
{
    @Override
    public void onCreate(final Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(cn.asiontang.xposed.url_firewall.R.layout.activity_main);

        //本Xposed模块
        {
            this.<CheckBox>findViewById(R.id.ckbEnable).setChecked(Config.get(getApplicationContext()).isEnable());
            this.<CheckBox>findViewById(R.id.ckbEnable).setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
            {
                @Override
                public void onCheckedChanged(final CompoundButton buttonView, final boolean isChecked)
                {
                    Config.get(getApplicationContext()).setEnable(isChecked);
                }
            });
        }

        //只捕获以下指定包名的APP
        {
            this.<EditText>findViewById(R.id.edtHookStringPackageName).setText(Config.get(getApplicationContext()).getHookStringPackageName());
            this.<EditText>findViewById(R.id.edtHookStringPackageName).addTextChangedListener(new TextWatcher()
            {
                @Override
                public void beforeTextChanged(final CharSequence s, final int start, final int count, final int after)
                {
                }

                @Override
                public void onTextChanged(final CharSequence s, final int start, final int before, final int count)
                {
                    Config.get(getApplicationContext()).setHookStringPackageName(s);
                }

                @Override
                public void afterTextChanged(final Editable s)
                {
                }
            });
        }

        //捕获常见的网络请求组件
        {
            this.<CheckBox>findViewById(R.id.ckbEnableHookHttpClient).setChecked(Config.get(getApplicationContext()).isEnableHookHttpClient());
            this.<CheckBox>findViewById(R.id.ckbEnableHookHttpClient).setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
            {
                @Override
                public void onCheckedChanged(final CompoundButton buttonView, final boolean isChecked)
                {
                    Config.get(getApplicationContext()).setEnableHookHttpClient(isChecked);
                }
            });
        }

        //捕获整个APP里用到的字符串
        {
            //这里设置为True 目的是为了后面的 setChecked=False 时,能正常触发 OnCheckedChangeListener,
            //后置设置 setChecked ,方便触发 onCheckedChanged 连带的设置关联控件的 setEnabled
            this.<CheckBox>findViewById(R.id.ckbEnableHookString).setChecked(!Config.get(getApplicationContext()).isEnableHookString());
            this.<CheckBox>findViewById(R.id.ckbEnableHookString).setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
            {
                @Override
                public void onCheckedChanged(final CompoundButton buttonView, final boolean isChecked)
                {
                    Config.get(getApplicationContext()).setEnableHookString(isChecked);

                    findViewById(R.id.ckbEnableHookStringWithContains).setEnabled(isChecked);
                    findViewById(R.id.ckbEnableHookStringWithLength).setEnabled(isChecked);
                    findViewById(R.id.ckbEnableHookStringAndReplace).setEnabled(isChecked);
                }
            });
            //后置设置 setChecked ,方便触发 onCheckedChanged 连带的设置关联控件的 setEnabled
            this.<CheckBox>findViewById(R.id.ckbEnableHookString).setChecked(Config.get(getApplicationContext()).isEnableHookString());
        }

        //只要包含以下字符串就记录
        {
            this.<CheckBox>findViewById(R.id.ckbEnableHookStringWithContains).setChecked(!Config.get(getApplicationContext()).isEnableHookStringWithContains());
            this.<CheckBox>findViewById(R.id.ckbEnableHookStringWithContains).setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
            {
                @Override
                public void onCheckedChanged(final CompoundButton buttonView, final boolean isChecked)
                {
                    findViewById(R.id.edtHookStringContainsText).setEnabled(isChecked);
                    Config.get(getApplicationContext()).setEnableHookStringWithContains(isChecked);
                }
            });
            this.<CheckBox>findViewById(R.id.ckbEnableHookStringWithContains).setChecked(Config.get(getApplicationContext()).isEnableHookStringWithContains());

            this.<EditText>findViewById(R.id.edtHookStringContainsText).setText(Config.get(getApplicationContext()).getHookStringContainsText());
            this.<EditText>findViewById(R.id.edtHookStringContainsText).addTextChangedListener(new TextWatcher()
            {
                @Override
                public void beforeTextChanged(final CharSequence s, final int start, final int count, final int after)
                {
                }

                @Override
                public void onTextChanged(final CharSequence s, final int start, final int before, final int count)
                {
                    Config.get(getApplicationContext()).setHookStringContainsText(s);
                }

                @Override
                public void afterTextChanged(final Editable s)
                {
                }
            });
        }

        //只要字符串长度和以下设置的一致就记录
        {
            this.<CheckBox>findViewById(R.id.ckbEnableHookStringWithLength).setChecked(!Config.get(getApplicationContext()).isEnableHookStringWithLength());
            this.<CheckBox>findViewById(R.id.ckbEnableHookStringWithLength).setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
            {
                @Override
                public void onCheckedChanged(final CompoundButton buttonView, final boolean isChecked)
                {
                    findViewById(R.id.edtHookStringLength).setEnabled(isChecked);
                    Config.get(getApplicationContext()).setEnableHookStringWithLength(isChecked);
                }
            });
            this.<CheckBox>findViewById(R.id.ckbEnableHookStringWithLength).setChecked(Config.get(getApplicationContext()).isEnableHookStringWithLength());

            this.<EditText>findViewById(R.id.edtHookStringLength).setText(String.valueOf(Config.get(getApplicationContext()).getHookStringLength()));
            this.<EditText>findViewById(R.id.edtHookStringLength).addTextChangedListener(new TextWatcher()
            {
                @Override
                public void beforeTextChanged(final CharSequence s, final int start, final int count, final int after)
                {
                }

                @Override
                public void onTextChanged(final CharSequence s, final int start, final int before, final int count)
                {
                    Config.get(getApplicationContext()).setHookStringLength(s);
                }

                @Override
                public void afterTextChanged(final Editable s)
                {
                }
            });
        }

        //字符串替换
        {
            this.<CheckBox>findViewById(R.id.ckbEnableHookStringAndReplace).setChecked(!Config.get(getApplicationContext()).isEnableHookStringAndReplace());
            this.<CheckBox>findViewById(R.id.ckbEnableHookStringAndReplace).setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
            {
                @Override
                public void onCheckedChanged(final CompoundButton buttonView, final boolean isChecked)
                {
                    findViewById(R.id.edtHookStringAndReplaceBefore).setEnabled(isChecked);
                    findViewById(R.id.edtHookStringAndReplaceAfter).setEnabled(isChecked);
                    Config.get(getApplicationContext()).setEnableHookStringAndReplace(isChecked);
                }
            });
            this.<CheckBox>findViewById(R.id.ckbEnableHookStringAndReplace).setChecked(Config.get(getApplicationContext()).isEnableHookStringAndReplace());

            this.<EditText>findViewById(R.id.edtHookStringAndReplaceBefore).setText(String.valueOf(Config.get(getApplicationContext()).getHookStringAndReplaceBefore()));
            this.<EditText>findViewById(R.id.edtHookStringAndReplaceBefore).addTextChangedListener(new TextWatcher()
            {
                @Override
                public void beforeTextChanged(final CharSequence s, final int start, final int count, final int after)
                {
                }

                @Override
                public void onTextChanged(final CharSequence s, final int start, final int before, final int count)
                {
                    Config.get(getApplicationContext()).setHookStringAndReplaceBefore(s);
                }

                @Override
                public void afterTextChanged(final Editable s)
                {
                }
            });
            this.<EditText>findViewById(R.id.edtHookStringAndReplaceAfter).setText(String.valueOf(Config.get(getApplicationContext()).getHookStringAndReplaceAfter()));
            this.<EditText>findViewById(R.id.edtHookStringAndReplaceAfter).addTextChangedListener(new TextWatcher()
            {
                @Override
                public void beforeTextChanged(final CharSequence s, final int start, final int count, final int after)
                {
                }

                @Override
                public void onTextChanged(final CharSequence s, final int start, final int before, final int count)
                {
                    Config.get(getApplicationContext()).setHookStringAndReplaceAfter(s);
                }

                @Override
                public void afterTextChanged(final Editable s)
                {
                }
            });
        }

        //测试 HTTP 协议
        //testApacheHttp("http://www.baidu.com/search/error.html?Http.Apache#this_ref_will_not_lost");
        //testHttpURLConnection("http://www.baidu.com/search/error.html?Http.URLConnection#this_ref_will_lost");//#后面的部分会丢失.

        //测试 HTTPS 协议
        //testApacheHttp("https://www.baidu.com/search/error.html?Https.Apache#this_ref_will_not_lost");
        //testHttpURLConnection("https://www.baidu.com/search/error.html?Https.URLConnection#this_ref_will_lost");
    }

    /**
     * 必须把 build.gradle 里的 compileSdkVersion 降低为19才不报错.
     */
    private void testApacheHttp(final String url)
    {
        new Thread()
        {
            @Override
            public void run()
            {
                try
                {
                    //NO.Suppor: HttpGet httpGet = new HttpGet(url);
                    //NO.Suppor: DefaultHttpClient defaultHttpClient = new DefaultHttpClient();
                    //NO.Suppor: HttpResponse httpResponse = defaultHttpClient.execute(httpGet);
                    //NO.Suppor: if (httpResponse.getStatusLine().getStatusCode() == 200)
                    //NO.Suppor:     LogEx.log(url, "网络正常");
                }
                catch (final Exception e)
                {
                    LogEx.log(e);
                }
            }
        }.start();
    }

    private void testHttpURLConnection(final String urlS)
    {
        new Thread()
        {
            @Override
            public void run()
            {
                super.run();
                HttpURLConnection connection = null;
                String msg = null;
                OutputStream outputStream = null;
                try
                {
                    final URL url = new URL(urlS);
                    connection = (HttpURLConnection) url.openConnection();
                    connection.setRequestMethod("POST");
                    //connection.setInstanceFollowRedirects(false);
                    connection.setConnectTimeout(60 * 1000);
                    connection.setReadTimeout(60 * 1000);

                    outputStream = connection.getOutputStream();
                    outputStream.write("test post data".getBytes("UTF-8"));
                    outputStream.flush();

                    if (200 == connection.getResponseCode())
                        msg = "当前网络正常";
                    else
                        msg = "网络连接失败";
                }
                catch (final Exception e)
                {
                    LogEx.log(e);
                    msg = "网络连接失败";
                }
                finally
                {
                    if (outputStream != null)
                        try
                        {
                            outputStream.close();
                        }
                        catch (IOException e)
                        {
                            e.printStackTrace();
                        }
                    if (connection != null)
                        connection.disconnect();
                }
                LogEx.log(urlS, msg);
            }
        }.start();
    }
}
